package com.nebula.salary.portal.controller.manage;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nebula.salary.common.constants.Const;
import com.nebula.salary.common.constants.ReturnMessage;
import com.nebula.salary.common.result.ServerResponse;
import com.nebula.salary.model.pojo.Common;
import com.nebula.salary.model.pojo.Navigation;
import com.nebula.salary.model.pojo.RoleNavigation;
import com.nebula.salary.portal.service.ICommonService;
import com.nebula.salary.portal.service.INavigationService;
import com.nebula.salary.portal.service.IRoleNavigationService;

/**
 * 菜单管理
 *
 * @author codex
 * @since 2022-02-24
 */
@RestController
@RequestMapping("/manage/page")
@Api(tags = "菜单管理")
public class MenuController {
    
    @Resource
    private INavigationService navigationService;
    
    @Resource
    private ICommonService commonService;
    
    @Resource
    private IRoleNavigationService roleNavigationService;
    
    @ApiOperation("删除菜单")
    @DeleteMapping("/{navId}")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse<String> delete(@ApiParam(value = "菜单ID", required = true)
    									 @PathVariable Integer navId) {
    	
    	// 校验菜单是否有子菜单
    	if (navigationService.hasChildByNavId(navId)) {
			return ServerResponse.createByErrorMessage("存在子菜单，不允许删除");
		}
    	
    	// 校验菜单是否已分配
    	if (navigationService.checkMenuExistRole(navId))
        {
            return ServerResponse.createByErrorMessage("菜单已分配，不允许删除");
        }

    	roleNavigationService.remove(new QueryWrapper<RoleNavigation>()
    			.eq(RoleNavigation.ROLE_ID, Const.HOST_ROLE_ID)
    			.eq(RoleNavigation.NAV_ID, navId));
    	return navigationService.removeById(navId)
    			? ServerResponse.createBySuccessMessage(ReturnMessage.DELETE_SUCCESS)
    			: ServerResponse.createByErrorMessage(ReturnMessage.DELETE_ERROR);
    }
    
    @ApiOperation("修改菜单")
    @PutMapping("/")
    public ServerResponse<String> update(@RequestBody Navigation navigation) {
        // 校验菜单名称是否唯一
        if (Const.NOT_UNIQUE.equals(navigationService.checkItemUnique(navigation))) {
            return ServerResponse.createByErrorMessage("修改菜单'" + navigation.getItem() + "'失败，菜单名称已存在");
        }
    
        // 校验显示排序是否唯一
        if (Const.NOT_UNIQUE.equals(navigationService.checkSortUnique(navigation))) {
            return ServerResponse.createByErrorMessage("修改菜单'" + navigation.getItem() + "'失败，显示排序已存在");
        }
    
        // 校验路由地址是否唯一
        if (Const.NOT_UNIQUE.equals(navigationService.checkPathUnique(navigation))) {
            return ServerResponse.createByErrorMessage("修改菜单'" + navigation.getItem() + "'失败，路由地址已存在");
        }
        
        return navigationService.update(navigation) > 0
                ? ServerResponse.createBySuccessMessage(ReturnMessage.UPDATE_SUCCESS)
                : ServerResponse.createByErrorMessage(ReturnMessage.UPDATE_ERROR);
    }
    
    @ApiOperation("新增菜单")
    @PostMapping("/")
    public ServerResponse<String> add(@RequestBody Navigation navigation) {    	
    	// 校验菜单名称是否唯一
    	if (Const.NOT_UNIQUE.equals(navigationService.checkItemUnique(navigation))) {
			return ServerResponse.createByErrorMessage("新增菜单'" + navigation.getItem() + "'失败，菜单名称已存在");
		}
    	
    	// 校验显示排序是否唯一
    	if (Const.NOT_UNIQUE.equals(navigationService.checkSortUnique(navigation))) {
			return ServerResponse.createByErrorMessage("新增菜单'" + navigation.getItem() + "'失败，显示排序已存在");
		}
    	
    	// 校验路由地址是否唯一
    	if (Const.NOT_UNIQUE.equals(navigationService.checkPathUnique(navigation))) {
			return ServerResponse.createByErrorMessage("新增菜单'" + navigation.getItem() + "'失败，路由地址已存在");
		}

    	return navigationService.add(navigation) > 0 
    			? ServerResponse.createBySuccessMessage(ReturnMessage.INSERT_SUCCESS)
    			: ServerResponse.createByErrorMessage(ReturnMessage.INSERT_ERROR);
    }
    
    @ApiOperation("根据菜单编号获取菜单信息")
    @GetMapping("/{navId}")
    public ServerResponse<Navigation> getInfoByNavId(@ApiParam(value = "菜单编号", required = true)
                                                     @PathVariable Integer navId) {
        return ServerResponse.createBySuccess(navigationService.getById(navId));
    }
    
    @ApiOperation("根据父菜单编号获取排序")
    @GetMapping("/getSort/{parentId}")
    
    public ServerResponse<Integer> getSortByParentId(@ApiParam(value = "父菜单编号", required = true)
                                                     @PathVariable Integer parentId) {
        String id;
        
        if (parentId.equals(0)) {
            id = "f_nav_sort";
        } else {
            id = "c_nav_sort";
        }
        
        Common common = commonService.getById(id);
        // 更新数据
        Integer sort = Integer.parseInt(common.getDef()) + 1;
        common.setDef(sort.toString());
        commonService.updateById(common);
        return ServerResponse.createBySuccess(sort);
    }
    
    @ApiOperation(value = "获取上级菜单")
    @GetMapping("/pList")
    public ServerResponse<List<Map<String, Object>>> getParentList() {
        QueryWrapper<Navigation> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(Navigation.NAV_ID + " as navId", Navigation.ITEM).eq(Navigation.PARENT_ID, 0);
        
        List<Map<String, Object>> resultList = navigationService.listMaps(queryWrapper);
        
        return ServerResponse.createBySuccess(resultList);
    }
    
    @ApiOperation(value = "获取菜单列表")
    @GetMapping("/")
    public ServerResponse<List<Navigation>> getList(@ApiParam(value = "菜单名称", required = false) String menuName) {
        QueryWrapper<Navigation> query = new QueryWrapper<>();
        query.eq(!Strings.isNullOrEmpty(menuName), Navigation.ITEM, menuName).orderByAsc(Navigation.SORT);
        
        return ServerResponse.createBySuccess(navigationService.buildTreeList(navigationService.list(query)));
    }
}
